package br.cnpq.webflowah.gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.net.URI;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.ListSelectionModel;
import javax.swing.WindowConstants;
import javax.swing.text.JTextComponent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import org.apache.log4j.Logger;
import org.mindswap.owl.OWLIndividual;
import org.mindswap.owls.OWLSFactory;
import org.mindswap.owls.process.Input;
import org.mindswap.owls.process.Output;
import org.mindswap.owls.process.OutputList;
import org.mindswap.owls.process.execution.ProcessExecutionEngine;
import org.mindswap.query.ValueMap;
import org.mindswap.swrl.Variable;
import org.mindswap.utils.URIUtils;

import br.cnpq.webflowah.adaptation.AdaptationConstants;
import br.cnpq.webflowah.adaptation.AdaptationManager;
import br.cnpq.webflowah.adaptation.ExecutionProcessMonitor;
import br.cnpq.webflowah.beans.Conceito;
import br.cnpq.webflowah.beans.Objetivo;
import br.cnpq.webflowah.beans.Operacao;
import br.cnpq.webflowah.beans.PlanQuality;
import br.cnpq.webflowah.beans.PlanoExecucao;
import br.cnpq.webflowah.beans.WorkflowSemantico;
import br.cnpq.webflowah.controle.GestorWorkflow;
import br.cnpq.webflowah.controle.SeletorPlanoExecucao;
import br.cnpq.webflowah.inferencia.CompositorSemantico;
import br.cnpq.webflowah.ontologia.ConceitoOWL;
import br.ufrn.opencopi.db.QualityParameterDB;
import br.ufrn.opencopi.db.ServiceDB;
import br.ufrn.opencopi.exceptions.AdaptationIsNotNecessaryException;
import br.ufrn.opencopi.exceptions.AdaptationIsNotPossibleException;
import br.ufrn.opencopi.graph.Graph;
import br.ufrn.opencopi.graph.GraphController;
import br.ufrn.opencopi.graph.GraphPath;
import br.ufrn.opencopi.util.XMLReader;

import com.hp.hpl.jena.vocabulary.XSD;

public class TelaExecutarWorkflow extends JDialog {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JPanel jCenterPane = null;
	private JPanel jToolBarPane = null;
	private JButton startButton = null;
	private JButton closeButton = null;
	private JPanel jParamPane = null;
	private JPanel jControlePane = null;
	private JLabel jLabel = null;
	private JScrollPane jScrollPane = null;
	private JTextArea jTextArea = null;
	private WorkflowSemantico workflow = null;
	private JScrollPane jScrollPane1 = null;
	private JScrollPane jScrollPane2 = null;
	private GestorWorkflow controle = null;
	private PlanoExecucao plano = null; // @jve:decl-index=0:
	private JPanel jInputPane = null;
	private JLabel jLabel1 = null;
	private JPanel jOutputPane = null;
	private JLabel jLabel2 = null;
	private Map<String, JComponent> entradas = null;
	private Map<String, JComponent> saidas = null;
	private JPanel jPlanoPane = null;
	private JScrollPane jScrollPane3 = null;
	private JLabel jLabel3 = null;
	private JTree jTree = null;
	private JSplitPane jSplitPane = null;
	private JPanel jPanel = null;
	private List<List<Operacao>> planList = null;
	private ExecutionProcessMonitor monitor = new ExecutionProcessMonitor();
	private ExecutionProcessMonitor newMonitor = new ExecutionProcessMonitor();
	// Salva a qualidade de todos os planos para que na fase de adapta��o n�o
	// seja necess�rio recalcular.
	private List<PlanQuality> planQualityList;
	private Graph graph;
	private GraphPath actualGraphPath;
	private static final Logger log = Logger
			.getLogger(TelaExecutarWorkflow.class);

	private void populateJTree(List<Operacao> caminho) {
		DefaultTreeModel tree = (DefaultTreeModel) jTree.getModel();
		DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getRoot();
		if (root.getChildCount() > 0)
			tree.removeNodeFromParent((DefaultMutableTreeNode) root
					.getFirstChild());

		for (int i = 0; i < caminho.size(); i++) {
			DefaultMutableTreeNode node = new DefaultMutableTreeNode(
					caminho.get(i));
			tree.insertNodeInto(node, root, root.getChildCount());
			jTree.expandPath(new TreePath(root.getPath()));
			root = node;
		}

	}

	// On press Execution button
	private class AbrirAction implements Runnable {
		public void run() {
			try {
				jTextArea.append("Starting the composition of services...\n");
				CompositorSemantico compositor = new CompositorSemantico();
				long iTimerComposition = System.currentTimeMillis();
				// lista de operaçoes que representam os planos
				List<List<Operacao>> list = compositor.doCompor(
						workflow.getEntradas(), workflow.getSaidas(),
						workflow.getObjetivos(), workflow.getDescartes());

				jTextArea.append("Composition successfully performed!\n"
						+ "\tGenerated " + list.size() + " plan(s)\n");
				jTextArea.append("Total time to composite the plans (ms): "
						+ (System.currentTimeMillis() - iTimerComposition)
						+ "\n");

				sortPlanList(list);
				workflow.setPlanos(planList);
				graph = GraphController.createGraph(workflow);
				preparaPlanExecution(workflow.getGrafo(), planList.get(0));
				startButton.setEnabled(true);
			} catch (Exception ex) {
				ex.printStackTrace();
				jTextArea.append("No plan was generated!\n\n");
				JOptionPane.showMessageDialog(TelaExecutarWorkflow.this,
						ex.getMessage(), "Mensagem", JOptionPane.ERROR_MESSAGE);
			}
		}
	};

	private class ExecutarAction implements Runnable {
		public void run() {
			ProcessExecutionEngine execEngine = OWLSFactory
					.createExecutionEngine();
			ValueMap values = new ValueMap();
			try {
				startButton.setEnabled(false);

				// limpar campos de saida
				Iterator iter = saidas.values().iterator();
				while (iter != null && iter.hasNext()) {
					JComponent cmp = (JComponent) iter.next();
					if (cmp instanceof JTextArea) {
						((JTextArea) cmp).setText(null);
					} else if (cmp instanceof JTextField) {
						((JTextField) cmp).setText(null);
						// } else if (cmp instanceof JCheckBox) {
						// ((JCheckBox)cmp).setSelected(false);
						// } else if (cmp instanceof JSpinner) {
						// ((JSpinner)cmp).setValue(null);
					} else {
						((JTextField) cmp).setText(null);
					}
				}
				jTextArea.append("Starting execution...\n");
				jTextArea.setCaretPosition(jTextArea.getText().length());
				jTextArea.append("Loading input parameters...\n");
				jTextArea.setCaretPosition(jTextArea.getText().length());

				// carregar os parametros de entrada
				iter = plano.getEntradas().iterator();
				while (iter.hasNext()) {
					Object value = null;
					Input input = (Input) iter.next();
					Variable param = plano.getEntradas().getParameter(
							input.getURI());
					// JComponent cmp = entradas.get(input.toString());
					JComponent cmp = entradas.get(plano.getEntrada(input
							.getURI()));
					if (cmp instanceof JTextComponent) {
						value = ((JTextComponent) cmp).getText();
					} else if (cmp instanceof JCheckBox) {
						value = new Boolean(((JCheckBox) cmp).isSelected());
					} else if (cmp instanceof JSpinner) {
						value = ((JSpinner) cmp).getValue();
					} else {
						value = ((JList) cmp).getSelectedValue();
					}
					if (input.getParamType().isDataType()) {
						values.setDataValue(param, value.toString());
						log.debug("Adicionei na valueMap a instancia"
								+ "\nParam: " + param + "\nValue: "
								+ value.toString());
					} else {
						values.setValue(param, plano
								.getIndividual(((Conceito) value).getURI()));
						log.debug("Adicionei na valueMap a instancia"
								+ "\n\t\tParam: "
								+ param
								+ "\n\t\tConceito: "
								+ plano.getIndividual(((Conceito) value)
										.getURI()));
					}
					jTextArea.append("\t[" + value.toString() + "]\n");
					jTextArea.setCaretPosition(jTextArea.getText().length());
				}
				jTextArea.append("Creating execution machine...\n");
				jTextArea.setCaretPosition(jTextArea.getText().length());
				// jTextArea.append("Executing the plan...\n");
				// jTextArea.setCaretPosition(jTextArea.getText().length());

				long iTimer = System.currentTimeMillis();
				execEngine.addMonitor(monitor);

				log.debug("variável values - Valores de entrada para o plano.\nVariáveis:\n"
						+ printDebugger(values.getVariables())
						+ "Valores:\n"
						+ printDebugger(values.getValues()) + "\n\n");

				org.mindswap.owls.process.Process pp = plano.getProcess();
				log.debug("variável process - Process\nInputs:\n"
						+ printDebugger(pp.getInputs()) + "Parameters:\n"
						+ printDebugger(pp.getParameters()) + "\n\n");
				execEngine.setAllowMultipleSatisifedPreconditions(true);
				ValueMap results = execEngine.execute(plano.getProcess(),
						values);

				log.debug("variável results - Valores de saída da máquina de execução.\nVariáveis: "
						+ results.getVariables()
						+ "\nValores: "
						+ results.getValues() + "\n\n");

				jTextArea
						.append("Execution Finished. Total execution time (ms): "
								+ (System.currentTimeMillis() - iTimer) + "\n");

				jTextArea.append("Obtaining output parameters...\n");
				jTextArea.setCaretPosition(jTextArea.getText().length());

				// imprimir os parametros de saida
				iter = plano.getSaidas().iterator();
				while (iter.hasNext()) {
					Output output = (Output) iter.next();
					// JComponent cmp = saidas.get(output.toString());
					JComponent cmp = saidas
							.get(plano.getSaida(output.getURI()));
					Object value = results.getValue(plano.getSaidas()
							.getParameter(output.getURI()));
					if (value == null)
						value = new Object();
					if (cmp instanceof JTextArea) {
						if (value instanceof OWLIndividual)
							((JTextArea) cmp).setText(((OWLIndividual) value)
									.toRDF());
						else
							((JTextArea) cmp).setText(value.toString());
						// } else if (cmp instanceof JTextField) {
						// ((JTextField)cmp).setText(value.toString());
						// } else if (cmp instanceof JCheckBox) {
						// ((JCheckBox)cmp).setSelected(((Boolean)
						// value).booleanValue());
						// } else if (cmp instanceof JSpinner) {
						// ((JSpinner)cmp).setValue(value);
					} else {
						((JTextField) cmp).setText(value.toString());
					}
				}
				jTextArea.append("Concluded!\n\n");
				jTextArea.setCaretPosition(jTextArea.getText().length());
				startButton.setEnabled(true);
			} catch (Exception e) {
				// ////////////////////////////////////////////////////////////////////////////////////////////////////
				// Iniciando adaptacao
				log.error("Iniciando o processo de adaptação. URI do processo em falha:\n"
						+ monitor.getAtualProcessURI());
				jTextArea.append("Error while executing the actual plan."
						+ "\nReason: " + e.getMessage() + "\n\n");
				jTextArea.append("Starting the adaptation process\n");

				PlanoExecucao newPlanoExecucao = new PlanoExecucao();
				DefaultMutableTreeNode root = null;

				// Locators aim to improve the Database performance
				QualityParameterDB.clearMetadataLocator();
				QualityParameterDB.clearAbsQualityParameterLocator();
				ServiceDB.clearLocator();

				Iterator<GraphPath> iii = graph.getPaths().iterator();
				List<List<Operacao>> novaLista = new LinkedList<List<Operacao>>();
				while (iii.hasNext()) {
					novaLista.add(iii.next().getPlan());
				}

				sortPlanList(novaLista);

				try {
					// FIXME: reordenar os planos de execução de acordo com os
					// novos valores dos metadados inseridos no BD

					long iTimerAdaptation = System.currentTimeMillis();
					// OK! - encontra o serviço em falha
					List<Operacao> OperacoesRestantes = AdaptationManager
							.prepareAdaptation(true, graph, actualGraphPath,
									AdaptationConstants.BALANCED,
									monitor.getAtualProcessURI(),
									planQualityList);
					// FIXME: pq é necessário criar newPlanoExecucao?
					newPlanoExecucao.setOperacoes(OperacoesRestantes);
					plano = newPlanoExecucao;
					List<Objetivo> listNewObjetivos = new LinkedList<Objetivo>();
					Iterator<Operacao> i = OperacoesRestantes.iterator();
					while (i.hasNext()) {
						listNewObjetivos.add(i.next().getObjetivo());
					}

					TreeModel treeM = workflow.getGrafo();
					root = (DefaultMutableTreeNode) treeM.getRoot();

					for (int j = 0; j < root.getChildCount(); j++) {
						DefaultMutableTreeNode child = (DefaultMutableTreeNode) root
								.getChildAt(j);
						if (child.getUserObject() instanceof Objetivo) {
							if (!listNewObjetivos.contains(child
									.getUserObject())) {
								root.remove(child);
								j--;
							} else
								break;

						}
					}

					jTextArea.append("Tempo total da adaptacao (ms): "
							+ (System.currentTimeMillis() - iTimerAdaptation)
							+ "\n");
					workflow.setGrafo(treeM);
					preparaPlanExecution(treeM, OperacoesRestantes);
					// ////////////////////////////////////////////////////////////////
					// limpar campos de saida
					Iterator itera = saidas.values().iterator();
					while (itera != null && itera.hasNext()) {
						JComponent cmp = (JComponent) itera.next();
						if (cmp instanceof JTextArea) {
							((JTextArea) cmp).setText(null);
						} else if (cmp instanceof JTextField) {
							((JTextField) cmp).setText(null);
							// } else if (cmp instanceof JCheckBox) {
							// ((JCheckBox)cmp).setSelected(false);
							// } else if (cmp instanceof JSpinner) {
							// ((JSpinner)cmp).setValue(null);
						} else {
							((JTextField) cmp).setText(null);
						}
					}
					jTextArea.append("Starting the execution...\n");
					jTextArea.setCaretPosition(jTextArea.getText().length());
					jTextArea.append("Loading input parameters...\n");
					jTextArea.setCaretPosition(jTextArea.getText().length());

					// FIXME: timer para selecionar instancias na interface
					Thread.sleep(6000);

					ValueMap newValues = new ValueMap();
					newValues.addMap(values);
					// carregar os parametros de entrada
					itera = plano.getEntradas().iterator();
					while (itera.hasNext()) {
						Object value = null;
						Input input = (Input) itera.next();
						Variable param = plano.getEntradas().getParameter(
								input.getURI());
						// JComponent cmp = entradas.get(input.toString());
						JComponent cmp = entradas.get(plano.getEntrada(input
								.getURI()));
						if (cmp instanceof JTextComponent) {
							value = ((JTextComponent) cmp).getText();
						} else if (cmp instanceof JCheckBox) {
							value = new Boolean(((JCheckBox) cmp).isSelected());
						} else if (cmp instanceof JSpinner) {
							value = ((JSpinner) cmp).getValue();
						} else {
							value = ((JList) cmp).getSelectedValue();
						}
						if (input.getParamType().isDataType()) {
							newValues.setDataValue(param, value.toString());
							log.debug("Adicionado o mapeamento: " + "\nParam: "
									+ param + "\nValue: "
									+ newValues.toString());
						} else {
							Conceito c = (Conceito) value;
							if (c != null && c.getURI() != null) {
								newValues.setValue(param, plano
										.getIndividual(((Conceito) value)
												.getURI()));
								log.debug("Adicionado o mapeamento: "
										+ "\n\t\tParam: "
										+ param
										+ "\n\t\tConceito: "
										+ plano.getIndividual(((Conceito) value)
												.getURI()));
							}
						}
						if (value != null)
							jTextArea.append("\t[" + value.toString() + "]\n");
						jTextArea
								.setCaretPosition(jTextArea.getText().length());
					}

					log.debug("variável plano\n" + "Novas operaçoes:\n"
							+ printDebugger(plano.getOperacoes())
							+ "\nEntradas:\n"
							+ printDebugger(plano.getEntradas())
							+ "\nSaídas:\n" + printDebugger(plano.getSaidas())
							+ "\n");

					org.mindswap.owls.process.Process newProcess = plano
							.getProcess();

					log.debug("variável newProcess - Novo Process\n"
							+ "Inputs:\n"
							+ printDebugger(newProcess.getInputs())
							+ "Parameters:\n"
							+ printDebugger(newProcess.getParameters()) + "\n");

					log.debug("variável newValues - Valores de entrada para o novo plano\n"
							+ "Variáveis:\n"
							+ printDebugger(newValues.getVariables())
							+ "Valores:\n"
							+ printDebugger(newValues.getValues()) + "\n\n");

					// Executar a adaptação
					jTextArea.append("Executing the adaptation plan......\n");
					ProcessExecutionEngine newProcEngine = OWLSFactory
							.createExecutionEngine();
					newProcEngine.addMonitor(newMonitor);

					iTimerAdaptation = System.currentTimeMillis();
					ValueMap results = newProcEngine.execute(
							plano.getProcess(), newValues);

					jTextArea.append("Total adaptation time(ms): "
							+ (System.currentTimeMillis() - iTimerAdaptation)
							+ "\n");
					// imprimir os parametros de saida
					Iterator<?> iter = plano.getSaidas().iterator();
					while (iter.hasNext()) {
						Output output = (Output) iter.next();
						JComponent cmp = saidas.get(plano.getSaida(output
								.getURI()));
						Object value = results.getValue(plano.getSaidas()
								.getParameter(output.getURI()));
						if (value == null)
							value = new Object();
						if (cmp instanceof JTextArea) {
							if (value instanceof OWLIndividual)
								((JTextArea) cmp)
										.setText(((OWLIndividual) value)
												.toRDF());
							else
								((JTextArea) cmp).setText(value.toString());
						} else {
							((JTextField) cmp).setText(value.toString());
						}
					}
					jTextArea.append("Concluded!\n\n");

					jTextArea.setCaretPosition(jTextArea.getText().length());
					startButton.setEnabled(true);
				} catch (AdaptationIsNotNecessaryException e2) {
					e2.printStackTrace();
				} catch (AdaptationIsNotPossibleException e2) {
					e2.printStackTrace();
				} catch (Exception e1) {
					e1.printStackTrace();
				}
				e.printStackTrace();
			}
		}
	}

	public static void executarWorkflow(Frame parent, WorkflowSemantico workflow) {
		TelaExecutarWorkflow tela = new TelaExecutarWorkflow(parent);
		tela.workflow = workflow;
		tela.controle = new GestorWorkflow();
		tela.setVisible(true);
	}

	private void montarCampos(List<URI> arg0, List<URI> arg1) throws Exception {
		this.entradas = new HashMap<String, JComponent>();
		this.saidas = new HashMap<String, JComponent>();

		// entradas
		int y = 0;
		JPanel jPanel1 = new JPanel();
		jPanel1.setLayout(new GridBagLayout());
		jPanel1.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));

		Iterator<URI> iter = arg0.iterator();
		while (iter.hasNext()) {
			String input = "" + iter.next();
			if (entradas.get(input) != null)
				continue;
			JComponent cmp = null;
			JComponent container = null;
			JLabel label1 = new JLabel(URIUtils.getLocalName(input) + ":");
			label1.setAlignmentX(Component.LEFT_ALIGNMENT);
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.gridx = 0;
			gridBagConstraints1.gridy = y++;
			gridBagConstraints1.insets = new Insets(5, 0, 0, 0);
			gridBagConstraints1.anchor = GridBagConstraints.NORTHWEST;
			jPanel1.add(label1, gridBagConstraints1);

			Conceito conceito = ConceitoOWL.recuperarTipo(URI.create(input));

			if (conceito.getAnotacao().equals(XSD.xstring.getURI())) {
				cmp = new JTextField();
				container = cmp;
			} else if (conceito.getAnotacao().equals(XSD.xboolean.getURI())) {
				cmp = new JCheckBox();
				container = cmp;
			} else if (conceito.getAnotacao().equals(XSD.decimal.getURI())
					|| conceito.getAnotacao().equals(XSD.integer.getURI())
					|| conceito.getAnotacao().equals(XSD.xint.getURI())
					|| conceito.getAnotacao().equals(XSD.xlong.getURI())) {
				cmp = new JSpinner();
				container = cmp;
			} else {
				cmp = new JList(new DefaultListModel());
				((JList) cmp)
						.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
				((JList) cmp).setVisibleRowCount(5);
				controle.doCarregar(((JList) cmp).getModel(),
						URI.create(conceito.getAnotacao()));
				container = new JScrollPane(cmp);
			}
			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
			gridBagConstraints2.gridx = 0;
			gridBagConstraints2.gridy = y++;
			gridBagConstraints2.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints2.anchor = GridBagConstraints.NORTHWEST;
			jPanel1.add(container, gridBagConstraints2);
			entradas.put(input, cmp);
		}
		GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
		gridBagConstraints5.gridx = 0;
		gridBagConstraints5.gridy = y;
		gridBagConstraints5.weightx = 1;
		gridBagConstraints5.weighty = 1;
		jPanel1.add(Box.createRigidArea(new Dimension(0, 0)),
				gridBagConstraints5);
		jScrollPane1.setViewportView(jPanel1);

		// saidas
		y = 0;
		JPanel jPanel2 = new JPanel();
		jPanel2.setLayout(new GridBagLayout());
		jPanel2.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
		// usar as saidas do plano no caso do usuario nao seleciona-las
		if (arg1.size() == 0) {
			OutputList out = plano.getSaidas();
			for (int i = 0; out != null && i < out.size(); i++) {
				String uri = plano.getSaida(out.outputAt(i).getURI());
				arg1.add(URI.create(uri));
			}
		}
		iter = arg1.iterator();
		while (iter.hasNext()) {
			String output = "" + iter.next();
			JComponent cmp = null;
			JComponent container = null;
			JLabel label1 = new JLabel(URIUtils.getLocalName(output) + ":");
			label1.setAlignmentX(Component.LEFT_ALIGNMENT);
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.gridx = 0;
			gridBagConstraints1.gridy = y++;
			gridBagConstraints1.insets = new Insets(5, 0, 0, 0);
			gridBagConstraints1.anchor = GridBagConstraints.NORTHWEST;
			jPanel2.add(label1, gridBagConstraints1);

			Conceito conceito = ConceitoOWL.recuperarTipo(URI.create(output));

			if (conceito.getAnotacao().equals(XSD.xstring.getURI())) {
				cmp = new JTextField();
				((JTextField) cmp).setEditable(false);
				container = cmp;
			} else {
				cmp = new JTextArea();
				((JTextArea) cmp).setEditable(false);
				((JTextArea) cmp).setRows(10);
				container = new JScrollPane(cmp);
			}
			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
			gridBagConstraints2.gridx = 0;
			gridBagConstraints2.gridy = y++;
			gridBagConstraints2.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints2.anchor = GridBagConstraints.NORTHWEST;
			jPanel2.add(container, gridBagConstraints2);
			saidas.put(output, cmp);
		}
		GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
		gridBagConstraints6.gridx = 0;
		gridBagConstraints6.gridy = y;
		gridBagConstraints6.weightx = 1;
		gridBagConstraints6.weighty = 1;
		jPanel2.add(Box.createRigidArea(new Dimension(0, 0)),
				gridBagConstraints6);
		jScrollPane2.setViewportView(jPanel2);
	}

	// private void montarCampos(PlanoExecucao pl) throws Exception {
	// this.plano = pl;
	// this.entradas = new HashMap<String, JComponent>();
	// this.saidas = new HashMap<String, JComponent>();
	//
	// // entradas
	// int y = 0;
	// JPanel jPanel1 = new JPanel();
	// // jPanel1.setLayout(new BoxLayout(jPanel1, BoxLayout.X_AXIS));
	// jPanel1.setLayout(new GridBagLayout());
	// jPanel1.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
	// // jPanel1.add(Box.createRigidArea(new Dimension(5,0)));
	// // Box mainbox = Box.createVerticalBox();
	// Iterator iter = plano.getEntradas().iterator();
	// while (iter.hasNext()) {
	// Input input = (Input) iter.next();
	// JComponent cmp = null;
	// JComponent container = null;
	// JLabel label1 = new JLabel(input.getLabel() + ":");
	// label1.setAlignmentX(Component.LEFT_ALIGNMENT);
	// GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
	// gridBagConstraints1.gridx = 0;
	// gridBagConstraints1.gridy = y++;
	// gridBagConstraints1.insets = new Insets(5,0,0,0);
	// gridBagConstraints1.anchor = GridBagConstraints.NORTHWEST;
	// jPanel1.add(label1, gridBagConstraints1);
	// // mainbox.add(label1);
	// if (input.getParamType().isDataType()) {
	// if (input.getParamType().toString().equals(XSD.xstring.getURI())) {
	// cmp = new JTextField();
	// // cmp.setSize(new Dimension(10,10));
	// } else if (input.getParamType().toString().equals(XSD.xboolean.getURI()))
	// {
	// cmp = new JCheckBox();
	// } else if (input.getParamType().toString().equals(XSD.decimal.getURI())
	// || input.getParamType().equals(XSD.integer.getURI()) ||
	// input.getParamType().equals(XSD.xint.getURI()) ||
	// input.getParamType().equals(XSD.xlong.getURI())) {
	// cmp = new JSpinner();
	// // cmp.setSize(new Dimension(10,10));
	// } else {
	// cmp = new JTextField();
	// // cmp.setSize(new Dimension(10,10));
	// }
	// container = cmp;
	// } else {
	// cmp = new JList(new DefaultListModel());
	// ((JList) cmp).setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	// ((JList) cmp).setVisibleRowCount(5);
	// controle.doCarregar(((JList) cmp).getModel(),
	// input.getParamType().getURI());
	// container = new JScrollPane(cmp);
	// }
	// // mainbox.add(container);
	// GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
	// gridBagConstraints2.gridx = 0;
	// gridBagConstraints2.gridy = y++;
	// gridBagConstraints2.fill = GridBagConstraints.HORIZONTAL;
	// gridBagConstraints2.anchor = GridBagConstraints.NORTHWEST;
	// jPanel1.add(container, gridBagConstraints2);
	// entradas.put(input.toString(), cmp);
	// // mainbox.add(Box.createRigidArea(new Dimension(0,5)));
	// }
	// // jPanel1.add(mainbox);
	// // jPanel1.add(Box.createRigidArea(new Dimension(5,0)));
	// GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
	// gridBagConstraints5.gridx = 0;
	// gridBagConstraints5.gridy = y;
	// gridBagConstraints5.weightx = 1;
	// gridBagConstraints5.weighty = 1;
	// jPanel1.add(Box.createRigidArea(new Dimension(0,0)),
	// gridBagConstraints5);
	// jScrollPane1.setViewportView(jPanel1);
	//
	// // saidas
	// y = 0;
	// JPanel jPanel2 = new JPanel();
	// jPanel2.setLayout(new GridBagLayout());
	// jPanel2.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
	// // jPanel2.setLayout(new BoxLayout(jPanel2, BoxLayout.X_AXIS));
	// // jPanel2.add(Box.createRigidArea(new Dimension(5,0)));
	// // mainbox = Box.createVerticalBox();
	// iter = plano.getSaidas().iterator();
	// while (iter.hasNext()) {
	// Output output = (Output) iter.next();
	// JComponent cmp = null;
	// JComponent container = null;
	// JLabel label1 = new JLabel(output.getLabel() + ":");
	// label1.setAlignmentX(Component.LEFT_ALIGNMENT);
	// GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
	// gridBagConstraints1.gridx = 0;
	// gridBagConstraints1.gridy = y++;
	// gridBagConstraints1.insets = new Insets(5,0,0,0);
	// gridBagConstraints1.anchor = GridBagConstraints.NORTHWEST;
	// jPanel2.add(label1, gridBagConstraints1);
	// // mainbox.add(label1);
	// if (output.getParamType().isDataType()) {
	// if (output.getParamType().toString().equals(XSD.xstring.getURI())) {
	// cmp = new JTextField();
	// // cmp.setPreferredSize(new Dimension(100,20));
	// ((JTextField) cmp).setEditable(false);
	// // } else if
	// (output.getParamType().toString().equals(XSD.xboolean.getURI())) {
	// // cmp = new JCheckBox();
	// // } else if
	// (output.getParamType().toString().equals(XSD.decimal.getURI()) ||
	// output.getParamType().equals(XSD.integer.getURI()) ||
	// output.getParamType().equals(XSD.xint.getURI()) ||
	// output.getParamType().equals(XSD.xlong.getURI())) {
	// // cmp = new JSpinner();
	// // cmp.setMaximumSize(new Dimension(200,20));
	// } else {
	// cmp = new JTextField();
	// // cmp.setPreferredSize(new Dimension(100,20));
	// ((JTextField) cmp).setEditable(false);
	// }
	// container = cmp;
	// } else {
	// cmp = new JTextArea();
	// // ((JTextArea)cmp).setLineWrap(true);
	// // ((JTextArea)cmp).setWrapStyleWord(true);
	// ((JTextArea)cmp).setEditable(false);
	// ((JTextArea)cmp).setRows(10);
	// container = new JScrollPane(cmp);
	// }
	// // mainbox.add(container);
	// GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
	// gridBagConstraints2.gridx = 0;
	// gridBagConstraints2.gridy = y++;
	// gridBagConstraints2.fill = GridBagConstraints.HORIZONTAL;
	// gridBagConstraints2.anchor = GridBagConstraints.NORTHWEST;
	// jPanel2.add(container, gridBagConstraints2);
	// saidas.put(output.toString(), cmp);
	// // mainbox.add(Box.createRigidArea(new Dimension(0,5)));
	// }
	// // jPanel2.add(mainbox);
	// // jPanel2.add(Box.createRigidArea(new Dimension(5,0)));
	// GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
	// gridBagConstraints6.gridx = 0;
	// gridBagConstraints6.gridy = y;
	// gridBagConstraints6.weightx = 1;
	// gridBagConstraints6.weighty = 1;
	// jPanel2.add(Box.createRigidArea(new Dimension(0,0)),
	// gridBagConstraints6);
	// jScrollPane2.setViewportView(jPanel2);
	// }

	/**
	 * @param owner
	 */
	private TelaExecutarWorkflow(Frame owner) {
		super(owner, "Run Workflow Semantic", true);
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(720, 540);
		this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		this.setContentPane(getJContentPane());
		this.addWindowListener(new java.awt.event.WindowAdapter() {
			public void windowOpened(java.awt.event.WindowEvent e) {
				Thread t = new Thread(new AbrirAction());
				t.start();
			}
		});
		this.setLocationRelativeTo(null);
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getJCenterPane(), BorderLayout.CENTER);
			jContentPane.add(getJToolBarPane(), BorderLayout.SOUTH);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jToolBarPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJToolBarPane() {
		if (jToolBarPane == null) {
			FlowLayout flowLayout = new FlowLayout();
			flowLayout.setAlignment(FlowLayout.RIGHT);
			jToolBarPane = new JPanel();
			jToolBarPane.setLayout(flowLayout);
			jToolBarPane.setPreferredSize(new Dimension(338, 41));
			jToolBarPane.add(getStartButton());
			jToolBarPane.add(getCloseButton());
		}
		return jToolBarPane;
	}

	/**
	 * This method initializes encerrarButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getStartButton() {
		if (startButton == null) {
			startButton = new JButton();
			startButton.setText("Start");
			startButton.setEnabled(false);
			startButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Thread t = new Thread(new ExecutarAction());
					t.start();
				}
			});
		}
		return startButton;
	}

	/**
	 * This method initializes cancelarButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getCloseButton() {
		if (closeButton == null) {
			closeButton = new JButton();
			closeButton.setText("Close");
			closeButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					dispose();
				}
			});
		}
		return closeButton;
	}

	/**
	 * This method initializes jCenterPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJCenterPane() {
		if (jCenterPane == null) {
			jCenterPane = new JPanel();
			jCenterPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
			jCenterPane.setLayout(new BorderLayout());
			jCenterPane.add(getJSplitPane(), BorderLayout.CENTER);
		}
		return jCenterPane;
	}

	/**
	 * This method initializes jParamPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJParamPane() {
		if (jParamPane == null) {
			jParamPane = new JPanel();
			jParamPane.setLayout(new BoxLayout(getJParamPane(),
					BoxLayout.X_AXIS));
			jParamPane.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
			jParamPane.add(getJInputPane(), null);
			jParamPane.add(getJOutputPane(), null);
		}
		return jParamPane;
	}

	/**
	 * This method initializes jControlePane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJControlePane() {
		if (jControlePane == null) {
			jLabel = new JLabel();
			jLabel.setText("Control");
			jControlePane = new JPanel();
			jControlePane.setLayout(new BorderLayout());
			jControlePane.setPreferredSize(new Dimension(48, 150));
			jControlePane.add(jLabel, BorderLayout.NORTH);
			jControlePane.add(getJScrollPane(), BorderLayout.CENTER);
		}
		return jControlePane;
	}

	/**
	 * This method initializes jScrollPane
	 * 
	 * @return javax.swing.JScrollPane
	 */
	private JScrollPane getJScrollPane() {
		if (jScrollPane == null) {
			jScrollPane = new JScrollPane();
			jScrollPane.setViewportView(getJTextArea());
		}
		return jScrollPane;
	}

	/**
	 * This method initializes jTextArea
	 * 
	 * @return javax.swing.JTextArea
	 */
	private JTextArea getJTextArea() {
		if (jTextArea == null) {
			jTextArea = new JTextArea();
			jTextArea.setEditable(false);
		}
		return jTextArea;
	}

	/**
	 * This method initializes jScrollPane1
	 * 
	 * @return javax.swing.JScrollPane
	 */
	private JScrollPane getJScrollPane1() {
		if (jScrollPane1 == null) {
			jScrollPane1 = new JScrollPane();
		}
		return jScrollPane1;
	}

	/**
	 * This method initializes jScrollPane2
	 * 
	 * @return javax.swing.JScrollPane
	 */
	private JScrollPane getJScrollPane2() {
		if (jScrollPane2 == null) {
			jScrollPane2 = new JScrollPane();
		}
		return jScrollPane2;
	}

	/**
	 * This method initializes jInputPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJInputPane() {
		if (jInputPane == null) {
			jLabel1 = new JLabel();
			jLabel1.setText("Inputs");
			jInputPane = new JPanel();
			jInputPane.setLayout(new BorderLayout());
			jInputPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
			jInputPane.add(jLabel1, BorderLayout.NORTH);
			jInputPane.add(getJScrollPane1(), BorderLayout.CENTER);
		}
		return jInputPane;
	}

	/**
	 * This method initializes jOutputPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJOutputPane() {
		if (jOutputPane == null) {
			jLabel2 = new JLabel();
			jLabel2.setText("Outputs");
			jOutputPane = new JPanel();
			jOutputPane.setLayout(new BorderLayout());
			jOutputPane.add(jLabel2, BorderLayout.NORTH);
			jOutputPane.add(getJScrollPane2(), BorderLayout.CENTER);
		}
		return jOutputPane;
	}

	/**
	 * This method initializes jPlanoPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPlanoPane() {
		if (jPlanoPane == null) {
			jLabel3 = new JLabel();
			jLabel3.setText("Flow of execution");
			jPlanoPane = new JPanel();
			jPlanoPane.setLayout(new BorderLayout());
			jPlanoPane.setPreferredSize(new Dimension(3, 70));
			jPlanoPane.add(getJScrollPane3(), BorderLayout.CENTER);
			jPlanoPane.add(jLabel3, BorderLayout.NORTH);
		}
		return jPlanoPane;
	}

	/**
	 * This method initializes jScrollPane3
	 * 
	 * @return javax.swing.JScrollPane
	 */
	private JScrollPane getJScrollPane3() {
		if (jScrollPane3 == null) {
			jScrollPane3 = new JScrollPane();
			jScrollPane3.setViewportView(getJTree());
		}
		return jScrollPane3;
	}

	/**
	 * This method initializes jTree
	 * 
	 * @return javax.swing.JTree
	 */
	private JTree getJTree() {
		if (jTree == null) {
			DefaultMutableTreeNode root = new DefaultMutableTreeNode();
			DefaultTreeModel model = new DefaultTreeModel(root);
			DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
			Icon personIcon = null;
			renderer.setLeafIcon(personIcon);
			renderer.setClosedIcon(personIcon);
			renderer.setOpenIcon(personIcon);
			jTree = new JTree(model);
			jTree.getSelectionModel().setSelectionMode(
					TreeSelectionModel.SINGLE_TREE_SELECTION);
			jTree.setCellRenderer(renderer);
			jTree.setRootVisible(false);
			jTree.setShowsRootHandles(true);
		}
		return jTree;
	}

	/**
	 * This method initializes jSplitPane
	 * 
	 * @return javax.swing.JSplitPane
	 */
	private JSplitPane getJSplitPane() {
		if (jSplitPane == null) {
			jSplitPane = new JSplitPane();
			jSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
			jSplitPane.setOneTouchExpandable(true);
			jSplitPane.setDividerLocation(100);
			jSplitPane.setBottomComponent(getJPanel());
			jSplitPane.setTopComponent(getJPlanoPane());
		}
		return jSplitPane;
	}

	/**
	 * This method initializes jPanel
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanel() {
		if (jPanel == null) {
			jPanel = new JPanel();
			jPanel.setLayout(new BorderLayout());
			jPanel.add(getJControlePane(), BorderLayout.SOUTH);
			jPanel.add(getJParamPane(), BorderLayout.CENTER);
		}
		return jPanel;
	}

	/**
	 * Cria a instancia de planList, que guarda a lista de planos em ordem de
	 * prioridade
	 * 
	 * @author fred
	 */
	private void sortPlanList(List<List<Operacao>> plans) {
		jTextArea.append("Starting the sort process of the plans...\n");
		Hashtable<String, Double> parameters = XMLReader.getParametersWeight();
		// Esta chamada faz com que todos os parametros do BD sejam recuperados
		// e armazenados em RAM
		SeletorPlanoExecucao seletor = new SeletorPlanoExecucao();
		seletor.startUp(plans);
		// ----> Aqui começa a contagem do tempo para seleção
		long iTimer = System.currentTimeMillis();
		planList = seletor.ordenaPlanoExecucao(plans, parameters);
		// pode ser usado na fase de adaptacao
		planQualityList = seletor.getPlanQualityList();
		jTextArea.append("Total time to sort the plans (ms): "
				+ (System.currentTimeMillis() - iTimer) + "\n");
	}

	public GraphPath getGraphPath(List<Operacao> exPlan) {
		Iterator<GraphPath> i = graph.getPaths().iterator();
		GraphPath gPath;
		while (i.hasNext()) {
			gPath = i.next();
			if (gPath.getPlan().equals(exPlan))
				return gPath;
		}
		return null;
	}

	private <T> String printDebugger(Iterable<T> collection) {
		StringBuffer buffer = new StringBuffer();
		for (T item : collection) {
			buffer.append("\t" + item + "\n");
		}
		return buffer.toString();
	}

	private void preparaPlanExecution(TreeModel treeModel,
			List<Operacao> caminho) {
		try {

			// jTextArea.append("Building GUI...\n");
			jTextArea.setCaretPosition(jTextArea.getText().length());
			actualGraphPath = getGraphPath(caminho);
			populateJTree(caminho);
			plano = controle.doCriarPlano(treeModel, caminho);
			montarCampos(workflow.getEntradas(), workflow.getSaidas());
			// /jTextArea.append("Successfully built the GUI!\n\n");
		} catch (IndexOutOfBoundsException ex) {
			ex.printStackTrace();
			jTextArea
					.append("No plan was generated becuse there are not more plan options!\n\n");
			JOptionPane.showMessageDialog(TelaExecutarWorkflow.this,
					ex.getMessage(), "Mensagem", JOptionPane.ERROR_MESSAGE);
		} catch (Exception ex) {
			ex.printStackTrace();
			jTextArea.append("No plan was generated!\n\n");
			JOptionPane.showMessageDialog(TelaExecutarWorkflow.this,
					ex.getMessage(), "Mensagem", JOptionPane.ERROR_MESSAGE);
		}

	}

}
